package com.sh.polymedicine.happysale.service.envelop;

import android.util.Log;

import com.sh.polymedicine.happysale.Interceptor.HeaderInterceptor;
import com.sh.polymedicine.happysale.net.entity.CashList;
import com.sh.polymedicine.happysale.net.entity.Definition;
import com.sh.polymedicine.happysale.net.entity.DirtyListResult;
import com.sh.polymedicine.happysale.net.entity.FaildBean;
import com.sh.polymedicine.happysale.net.entity.MediaPlayList;
import com.sh.polymedicine.happysale.net.entity.Region;
import com.sh.polymedicine.happysale.net.entity.UserToken;
import com.sh.polymedicine.happysale.result.InfoResult;
import com.sh.polymedicine.happysale.result.ListResult;
import com.sh.polymedicine.happysale.result.PageResult;
import com.sh.polymedicine.happysale.result.SimpleResult;
import com.sh.polymedicine.happysale.result.UserInfoRep;
import com.sh.polymedicine.happysale.result.UserInfoResult;
import com.sh.polymedicine.happysale.result.WalletResult;
import com.sh.polymedicine.happysale.service.IHappySaleManager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;


/**
 * Created by zhouyucheng on 2017/9/19.
 */

public class HappySaleManager {
    private String TAG = "HappySaleManager";

    private static HappySaleManager mPolyManager;

    private static final String divider = "/";

    private IHappySaleManager iHappySaleManager;

    private static final int DEFAULT_TIMEOUT = 5;

    /**
     * POLYPOART_ADDRESS,例如:http://192.168.3.20 方便调试
     */
    private String PORTAL_ADDRESS;


    private String regionCode;

    private String terminal_type;

    private HeaderInterceptor.AccessTokenRfresh mAccessTokenRfresh;


    public static String DATA_NULL = "DATA_NULL";
    public static String DATA_FAIL = "DATA_FAIL";
    public static String NET_ERROR = "NET_ERROR";
    public static String DATA_NULL_DEP = "返回数据为NULL";

    private HappySaleManager(String portalAddress, String terminal_type, String regionCode, HeaderInterceptor.AccessTokenRfresh mAccessTokenRfresh) {
        this.regionCode = regionCode;
        this.terminal_type = terminal_type;
        this.mAccessTokenRfresh = mAccessTokenRfresh;
        if (portalAddress != null && portalAddress.trim().length() > 0) {
            if (!portalAddress.endsWith("/")) {
                this.PORTAL_ADDRESS = portalAddress + divider;
            } else {
                // 兼容老的项目
                this.PORTAL_ADDRESS = portalAddress;
            }
        }


        // An OkHttp interceptor which logs HTTP request and response data.
        //  HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
//        logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
        //   logging.setLevel(HttpLoggingInterceptor.Level.BODY);

        HeaderInterceptor headerInterceptor = new HeaderInterceptor(mAccessTokenRfresh);

        //手动创建一个OkHttpClient并设置超时时间
        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
        httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
        httpClientBuilder.addInterceptor(headerInterceptor);


        // SSLSocketFactory sslSocketFactory = new SslContextFactory().getSslSocket().getSocketFactory();
        // httpClientBuilder = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory);
        Retrofit mRetrofit = new Retrofit.Builder()
                .client(httpClientBuilder.build())
                .baseUrl(PORTAL_ADDRESS)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        iHappySaleManager = mRetrofit.create(IHappySaleManager.class);

    }

    public static HappySaleManager getInstence() {
        return mPolyManager;
    }


    private class DirtyListResultFactory<T> implements Func1<DirtyListResult<T>, MediaPlayList> {
        private Subscriber subscriber;

        public DirtyListResultFactory(Subscriber<T> sub) {
            this.subscriber = sub;
        }

        @Override
        public MediaPlayList call(DirtyListResult<T> tBaseBean) {
            if (tBaseBean == null) {
                /**
                 * API 17
                 */
                this.subscriber.onError(new Throwable(DATA_FAIL, new Throwable(FaildBean.RESULT_NULL + "", new Throwable(""))));
                return null;
            }
            String ret = tBaseBean.getRet();
            Map<String, Object> program = tBaseBean.getProgram();
            if ("0".equals(ret)) {
                List<Definition> list = (List<Definition>) tBaseBean.getList();

                for (Definition info : list) {
                    info.setName(program.get("name").toString());
                    info.setDuration(program.get("duration").toString());
                }

                MediaPlayList media = new MediaPlayList();
                media.setList(list);
                media.setFavorite(tBaseBean.isFavorite());
                return media;
            } else {
                this.subscriber.onError(new Throwable(DATA_FAIL, new Throwable(ret, new Throwable(tBaseBean.getDesc()))));
                if (!this.subscriber.isUnsubscribed()) {
                    this.subscriber.unsubscribe();
                }
                return null;
            }
        }
    }

    /**
     * 健康2.0 ———— 2.6获取节目视频播放地址(原接口4.1)
     *
     * @param subscriber onError()观察者
     * @return Observable
     */
    public Observable getHealthyVodMediaPlayList(String id, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("programId", id);
        return iHappySaleManager.getHealthyVodMediaPlayList(regionCode, terminal_type, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new DirtyListResultFactory<Definition>(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public static final class Builder {

        /**
         * 域名、服务器地址
         */
        private String mPortalAddress;
        /**
         * PORTAL
         */
        private String mPortalType;
        /**
         * 终端类型
         */
        private String mTerminalType;
        /**
         * 区域ID
         */
        private String mRegionCode;


        private HeaderInterceptor.AccessTokenRfresh mAccessTokenRfresh;

        public Builder() {

        }

        public Builder AccessTokenRfresh(HeaderInterceptor.AccessTokenRfresh mAccessTokenRfresh) {
            this.mAccessTokenRfresh = mAccessTokenRfresh;
            return this;
        }

        /**
         * 设置域名
         *
         * @param baseUrl PORTAL地址 ———— 例：http://192.168.3.20
         * @return Builder
         */
        public Builder portalAddress(String baseUrl) {
            this.mPortalAddress = baseUrl;
            return this;
        }


        /**
         * 设置PORTAL名
         *
         * @param portalType 接口对应PORTAL
         * @return Builder
         */
        public Builder portalType(String portalType) {
            this.mPortalType = portalType;
            return this;
        }

        /**
         * 设置终端类型 terminal_type
         *
         * @param terminal_type 终端类型terminal_type
         * @return Builder
         */
        public Builder terminalType(String terminal_type) {
            this.mTerminalType = terminal_type;
            return this;
        }

        /**
         * 设置区域ID
         *
         * @param regionCode 区域ID
         * @return Builder
         */
        public Builder regionCode(String regionCode) {
            this.mRegionCode = regionCode;
            return this;
        }


        public HappySaleManager build() {
            mPolyManager = new HappySaleManager(mPortalAddress,
                    mTerminalType, mRegionCode, mAccessTokenRfresh);
            return mPolyManager;
        }
    }

/**********************数据返回***********************/
    /**
     * 用来统一处理Http的resultCode,并将HttpResult的Data部分剥离出来返回给subscriber
     *
     * @param <T> Subscriber真正需要的数据类型，也就是Data部分的数据类型
     */
    private class ListResultFactory<T> implements Func1<ListResult<T>, List<T>> {
        private Subscriber subscriber;

        public ListResultFactory(Subscriber<T> sub) {
            this.subscriber = sub;
        }

        @Override
        public List<T> call(ListResult<T> tBaseBean) {
            if (tBaseBean == null) {
                return null;
            }
            String ret = tBaseBean.getRet();
            if ("0".equals(ret)) {
                return tBaseBean.getList();
            } else {
                this.subscriber.onError(new Throwable(DATA_FAIL, new Throwable(ret, new Throwable(tBaseBean.getDesc()))));
                if (!this.subscriber.isUnsubscribed()) {
                    this.subscriber.unsubscribe();
                }
                return null;
            }
        }
    }

    /**
     * infoResult  返回一个对象信息
     */
    private class InfoResultFactory<T> implements Func1<InfoResult<T>, T> {
        private Subscriber subscriber;

        public InfoResultFactory(Subscriber<T> sub) {
            this.subscriber = sub;
        }

        @Override
        public T call(InfoResult<T> tBaseBean) {
            if (tBaseBean == null) {
                this.subscriber.onError(new Throwable(DATA_NULL, new Throwable(DATA_NULL_DEP)));
                return null;
            }
            String ret = tBaseBean.getRet();
            if ("0".equals(ret)) {
                return tBaseBean.getUserToken();
            } else {
                this.subscriber.onError(new Throwable(DATA_FAIL, new Throwable(ret, new Throwable(tBaseBean.getDesc()))));
                if (!this.subscriber.isUnsubscribed()) {
                    this.subscriber.unsubscribe();
                }
                return null;
            }
        }
    }

    /**
     * PageResult 返回分页信息数据
     *
     * @param <T>
     */
    private class PageResultFactory<T> implements Func1<PageResult<T>, PageResult<T>> {
        private Subscriber subscriber;

        public PageResultFactory(Subscriber<T> sub) {
            this.subscriber = sub;
        }

        @Override
        public PageResult<T> call(PageResult<T> tBaseBean) {
            if (tBaseBean == null) {
                this.subscriber.onError(new Throwable(DATA_FAIL, new Throwable(DATA_NULL_DEP)));
                return null;
            }
            String ret = tBaseBean.getRet();
            if ("0".equals(ret)) {
                PageResult mPage = new PageResult();
                mPage.setFirstPage(tBaseBean.isFirstPage());
                mPage.setLastPage(tBaseBean.isLastPage());
                mPage.setNextPage(tBaseBean.getNextPage());
                mPage.setPageNo(tBaseBean.getPageNo());
                mPage.setPrePage(tBaseBean.getPrePage());
                mPage.setTotalCount(tBaseBean.getTotalCount());
                mPage.setTotalPage(tBaseBean.getTotalPage());
                mPage.setUrl(tBaseBean.getUrl());
                mPage.setTypeTotal(tBaseBean.getTypeTotal());
                mPage.setList((List<T>) tBaseBean.getList());
                return mPage;
            } else {
                this.subscriber.onError(new Throwable(DATA_FAIL, new Throwable(ret, new Throwable(tBaseBean.getDesc()))));
                if (!this.subscriber.isUnsubscribed()) {
                    this.subscriber.unsubscribe();
                }
                return null;
            }
        }
    }

    /**
     * 简单返回只有ret值
     *
     * @param <T>
     */
    private class SimpleResultFactory<T> implements Func1<SimpleResult, T> {
        private Subscriber subscriber;

        public SimpleResultFactory(Subscriber<T> sub) {
            this.subscriber = sub;
        }

        @Override
        public T call(SimpleResult tBaseBean) {
            if (tBaseBean == null) {
                this.subscriber.onError(new Throwable(DATA_NULL, new Throwable(DATA_NULL_DEP)));
                return null;
            }
            String ret = tBaseBean.getRet();
            if ("0".equals(ret)) {
                return (T) tBaseBean;
            } else {
                this.subscriber.onError(new Throwable(DATA_FAIL, new Throwable(ret, new Throwable(tBaseBean.getDesc()))));
                if (!this.subscriber.isUnsubscribed()) {
                    this.subscriber.unsubscribe();
                }
                return null;
            }
        }
    }


    private class UserInfoResultFactory<T> implements Func1<UserInfoRep<T>, T> {
        private Subscriber subscriber;

        public UserInfoResultFactory(Subscriber<T> sub) {
            this.subscriber = sub;
        }

        @Override
        public T call(UserInfoRep<T> tBaseBean) {
            if (tBaseBean == null) {
                this.subscriber.onError(new Throwable(DATA_NULL, new Throwable(DATA_NULL)));
                return null;
            }
            String ret = tBaseBean.getRet();
            if ("0".equals(ret)) {
                return tBaseBean.getInfo();
            } else {
                this.subscriber.onError(new Throwable(DATA_FAIL, new Throwable(ret, new Throwable(tBaseBean.getDesc()))));
                if (!this.subscriber.isUnsubscribed()) {
                    this.subscriber.unsubscribe();
                }
                return null;
            }
        }
    }
    /**
     * 钱包信息返回
     *
     * @param <T>
     */
    private class WalletResultFactory<T> implements Func1<WalletResult, T> {
        private Subscriber subscriber;

        public WalletResultFactory(Subscriber<T> sub) {
            this.subscriber = sub;
        }

        @Override
        public T call(WalletResult tBaseBean) {
            if (tBaseBean == null) {
                this.subscriber.onError(new Throwable(DATA_NULL, new Throwable(DATA_NULL_DEP)));
                return null;
            }
            String ret = tBaseBean.getRet();
            if ("0".equals(ret)) {
                return (T) tBaseBean;
            } else {
                this.subscriber.onError(new Throwable(DATA_FAIL, new Throwable(ret, new Throwable(tBaseBean.getDesc()))));
                if (!this.subscriber.isUnsubscribed()) {
                    this.subscriber.unsubscribe();
                }
                return null;
            }
        }
    }
    /*********************接口**************************/

    /**
     * 2.1	微信登陆
     *
     * @param authorizationCode 微信登陆授权码，（String 不可为空）
     * @param deviceId          设备唯一标识，同一个设备应保存该值不会变化（String 不可为空）
     * @param subscriber
     * @return
     */
    public Observable weixinLogin(String authorizationCode, String deviceId, Subscriber subscriber) {

        Log.i(TAG, "微信拉取信息: code" + authorizationCode);
        Log.i(TAG, "微信设备信息: IMEI" + deviceId);
        Map<String, Object> map = new HashMap<>();
        map.put("authorizationCode", authorizationCode);
        map.put("deviceId", deviceId);
        return iHappySaleManager.weixinLogin(map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new InfoResultFactory<UserToken>(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.2	发送短信验证码
     *
     * @param mobile     电话号码
     * @param subscriber
     * @return
     */
    public Observable sendVerificationCode(String mobile, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("mobile", mobile);
        return iHappySaleManager.sendVerificationCode(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.3绑定手机
     *
     * @param mobile           电话号码
     * @param verificationCode 验证码
     * @param userSign         签名
     * @param subscriber
     * @return
     */
    public Observable bindMobile(String mobile, String verificationCode, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("mobile", mobile);
        map.put("verificationCode", verificationCode);
        return iHappySaleManager.bindMobile(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.4 保存这个人信息
     *
     * @param nick       昵称
     * @param regionId   区域
     * @param realName   真实姓名
     * @param userSign
     * @param subscriber
     * @return
     */
    public Observable saveMyInfo(String nick, String regionId, String realName, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("nick", nick);
        map.put("regionId", regionId);
        map.put("realName", realName);
        return iHappySaleManager.saveMyInfo(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.8 用户信息返回
     *
     * @param userId     用户id
     * @param userSign
     * @param subscriber
     * @return
     */
    public Observable userInfo(String userId, String userSign, Subscriber subscriber) {
        Log.i(TAG, "userId: " + userId);
        Log.i(TAG, "userSign: " + userSign);
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        return iHappySaleManager.userInfo(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new UserInfoResultFactory<UserInfoResult>(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.9 绑定销售经理
     *
     * @param userId     用户id
     * @param userSign
     * @param subscriber
     * @return
     */
    public Observable bindManager(String userId, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        return iHappySaleManager.bindManager(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.10  我的钱包
     *
     * @param userSign
     * @param subscriber
     * @return
     */
    public Observable mineWallet(String userId, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        return iHappySaleManager.mineWallet(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new WalletResultFactory<WalletResult>(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    /**
     * 3.11 提现历史记录
     *
     * @param userSign
     * @param subscriber
     * @return
     */
    public Observable cashList(String pageNo, String pageSize, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("pageNo", pageNo);
        map.put("pageSize", pageSize);
        return iHappySaleManager.cashList(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new PageResultFactory<CashList>(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.12  提现说明
     *
     * @param userSign
     * @param subscriber
     * @return
     */
    public Observable withdrawDescription(String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        return iHappySaleManager.withdrawDescription(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    /**
     * 3.13 提现
     *
     * @param amount     金额
     * @param userSign
     * @param subscriber
     * @return
     */
    public Observable cash(String amount, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("amount", amount);
        return iHappySaleManager.cash(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.14 QQ群
     *
     * @param userSign
     * @param subscriber
     * @return
     */
    public Observable discussQq(String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        return iHappySaleManager.discussQq(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.15 用户反馈
     *
     * @param content
     * @param subscriber
     * @return
     */
    public Observable feedback(String content, String phone, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("content", content);
        map.put("phone", phone);
        return iHappySaleManager.feedback(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.16 关于我们
     *
     * @param subscriber
     * @return
     */
    public Observable aboutUs(String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        return iHappySaleManager.aboutUs(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.17	我的个人信息
     *
     * @param userSign
     * @param subscriber
     * @return
     */
    public Observable userInfo2(String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        return iHappySaleManager.userInfo2(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new UserInfoResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.18 生成二维码
     *
     * @param subscriber
     * @return
     */
    public Observable makePortrait(String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        return iHappySaleManager.makePortrait(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    /**
     * 3.19 上传头像
     *
     * @param subscriber
     * @return
     */
    public Observable updatePortrait(String image, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("image", image);
        map.put("type", "png");

        return iHappySaleManager.updatePortrait(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    /**
     * 3.20 修改昵称
     *
     * @param subscriber
     * @return
     */
    public Observable changeNick(String nickname, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("nickname", nickname);
        return iHappySaleManager.changeNick(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.21 修改地区
     *
     * @param subscriber
     * @return
     */
    public Observable changeRegion(String region, String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("region", region);
        return iHappySaleManager.changeRegion(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new SimpleResultFactory(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 3.21 修改地区
     *
     * @param subscriber
     * @return
     */
    public Observable getRegionList(String userSign, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        return iHappySaleManager.getRegionList(userSign, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new ListResultFactory<Region>(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }
}

